package com.sf.fy.uav.applet.user.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sf.fy.uav.applet.order.service.OrderService;
import com.sf.fy.uav.applet.user.service.AboutUserService;
import com.sf.fy.uav.common.awt.JwtUtil;
import com.sf.fy.uav.common.enums.*;
import com.sf.fy.uav.common.exception.BusinessException;
import com.sf.fy.uav.common.request.order.SelectOrderRequest;
import com.sf.fy.uav.common.request.order.task.*;
import com.sf.fy.uav.common.response.IdResponse;
import com.sf.fy.uav.common.response.order.LogisticsDetailResponse;
import com.sf.fy.uav.common.response.order.UserFeedbackResponse;
import com.sf.fy.uav.common.response.order.task.GoodsTypeResponse;
import com.sf.fy.uav.common.response.order.task.TaskStatusLogResponse;
import com.sf.fy.uav.common.response.user.OrderDetailResponse;
import com.sf.fy.uav.common.utils.BeanUtil;
import com.sf.fy.uav.common.utils.PhoneEncoderUtil;
import com.sf.fy.uav.common.utils.RespJsonPageData;
import com.sf.fy.uav.controller.ErrandOrderController;
import com.sf.fy.uav.entity.Coupon;
import com.sf.fy.uav.entity.ErrandOrder;
import com.sf.fy.uav.entity.UserCoupon;
import com.sf.fy.uav.good.entity.CityGoodsType;
import com.sf.fy.uav.good.entity.GoodsSoundRecording;
import com.sf.fy.uav.good.entity.GoodsType;
import com.sf.fy.uav.good.entity.TaskGoods;
import com.sf.fy.uav.good.mapper.CityGoodsTypeMapper;
import com.sf.fy.uav.good.mapper.GoodsSoundRecordingMapper;
import com.sf.fy.uav.good.mapper.GoodsTypeMapper;
import com.sf.fy.uav.good.mapper.TaskGoodsMapper;
import com.sf.fy.uav.mapper.CouponMapper;
import com.sf.fy.uav.mapper.ErrandOrderMapper;
import com.sf.fy.uav.mapper.UserCouponMapper;
import com.sf.fy.uav.order.controller.CityAirportRest;
import com.sf.fy.uav.order.controller.FeedbackRest;
import com.sf.fy.uav.order.controller.FeedbackStatusLogRest;
import com.sf.fy.uav.order.entity.*;
import com.sf.fy.uav.order.mapper.*;
import com.sf.fy.uav.order.service.IFeedbackService;
import com.sf.fy.uav.rest.controller.TtTesTerminalRest;
import com.sf.fy.uav.rest.entity.TtTesTerminal;
import com.sf.fy.uav.task.controller.TaskStatusLogRest;
import com.sf.fy.uav.task.entity.Airport;
import com.sf.fy.uav.task.entity.Task;
import com.sf.fy.uav.task.entity.TaskStatusLog;
import com.sf.fy.uav.task.mapper.AirportMapper;
import com.sf.fy.uav.task.mapper.TaskMapper;
import com.sf.fy.uav.task.mapper.TaskStatusLogMapper;
import com.sf.fy.uav.task.rest.AirStationRest;
import com.sf.fy.uav.task.rest.IntraCityRest;
import com.sf.fy.uav.task.service.AirStationService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author LTQ
 */
@Service
public class AboutUserServiceImpl implements AboutUserService {

    private final static Logger logger = LoggerFactory.getLogger(AboutUserServiceImpl.class);
    @Autowired
    private AirStationRest airStationRest;

    @Autowired
    private IntraCityRest intraCityRest;

    @Autowired
    private UserCouponMapper userCouponMapper;
    @Autowired
    private TaskMapper taskMapper;

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private FeedbackMapper feedbackMapper;

    @Autowired
    private AirportMapper airportMapper;

    @Autowired
    private CouponMapper couponMapper;

    @Autowired
    private CityAirportRest cityAirportRest;

    @Autowired
    private TaskGoodsMapper taskGoodsMapper;

    @Autowired
    private TaskStatusLogMapper taskStatusLogMapper;

    @Autowired
    private GoodsSoundRecordingMapper goodsSoundRecordingMapper;

    @Autowired
    private GoodsTypeMapper goodsTypeMapper;

    @Autowired
    private FeedbackStatusLogMapper feedbackStatusLogMapper;

    @Autowired
    private FeedbackStatusLogRest feedbackStatusLogRest;

    @Autowired
    private CityGoodsTypeMapper cityGoodsTypeMapper;

    @Autowired
    private IFeedbackService iFeedbackService;

    @Autowired
    private ExpenseDetailsMapper expenseDetailsMapper;

    @Autowired
    private ErrandOrderController errandOrderController;

    @Autowired
    private FeedbackRest feedbackRest;

    @Autowired
    private AirStationService airStationService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private PhoneEncoderUtil phoneEncoderUtil;


    @Value("${file.path:/usr/local/applet/}")
    private String baseUrl;

    @Value("${max-ing-task-num:4}")
    private String maxIngTaskNum;

    @Autowired
    private TaskStatusLogRest taskStatusLogRest;


    @Autowired
    private TtTesTerminalRest ttTesTerminalRest;

    @Override
    public IdResponse addTask(TaskRequest taskRequest) {
        /**
         * 1.请求站点，并保存
         * 2.生成任务
         */
        Airport airport;
        IdResponse idResponse = new IdResponse();
        Date date = new Date();
        SitesRequest sitesRequest = new SitesRequest();
        sitesRequest.setLatitude(taskRequest.getLatitude().doubleValue());
        sitesRequest.setLongitude(taskRequest.getLongitude().doubleValue());
        JSONObject jsonObject = airStationRest.getAvailableDeliveryStations(sitesRequest);

        if (jsonObject.getBoolean("success")) {
            if ((Boolean) ((HashMap) jsonObject.get("obj")).get("isHasAirport")) {
                HashMap airportObj = (HashMap) ((HashMap) jsonObject.get("obj")).get("airport");
                QueryWrapper<Airport> airportQueryWrapper = new QueryWrapper<>();
                airportQueryWrapper.eq("code", airportObj.get("code"));
                airport = airportMapper.selectOne(airportQueryWrapper);
                Boolean isInsert = false;
                if (ObjectUtils.isEmpty(airport)) {
                    isInsert = true;
                    airport = new Airport();
                    airport.setId(UUID.randomUUID().toString().replaceAll("-", ""));
                    airport.setCreateTime(date);
                    airport.setCode((String) airportObj.get("code"));
                }
                airport.setUpdateTime(date);
                airport.setManagerPhone((String) airportObj.get("managerPhone"));
                airport.setManagerName((String) airportObj.get("managerName"));
                airport.setLatitude((Double) airportObj.get("latitude"));
                airport.setName((String) airportObj.get("name"));
                airport.setLongitude((Double) airportObj.get("longitude"));
                if (isInsert) {
                    airportMapper.insert(airport);
                } else {
                    airportMapper.updateById(airport);
                }
                idResponse.setId(airport.getId());
                idResponse.setName(airport.getName());
            }

        }

        return idResponse;
    }

    @Override
    public JSONObject getOrderInfo(String orderCode) {
        JSONObject jsonObject = airStationRest.getOrderInfo(orderCode);
        return jsonObject;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Date expireOrder(String id) {
        OrderInfo orderInfo = orderInfoMapper.selectById(id);
        if (ObjectUtils.isEmpty(orderInfo)) {
            throw new RuntimeException("订单不存在");
        } else {
            if (orderInfo.getOrderStatus().equals(OrderStatusEnum.TO_BE_PAID.getStatus())) {
                orderInfo.setOrderStatus(OrderStatusEnum.EXPIRE.getStatus());
                Date date = new Date();
                orderInfo.setUpdateTime(date);
                orderInfoMapper.updateById(orderInfo);
                String userCouponId = orderInfo.getUserCouponId();
                if (!ObjectUtils.isEmpty(userCouponId)) {
                    UserCoupon userCoupon = userCouponMapper.selectById(userCouponId);
                    if (UserCouponStatusEnum.USED.getValue().equals(userCoupon.getStatus())) {
                        userCoupon.setStatus(UserCouponStatusEnum.NOT_USED.getValue());
                        userCoupon.setUseTime(null);
                        userCoupon.setUpdateTime(date);
                        userCouponMapper.updateById(userCoupon);
                        String couponId = userCoupon.getCouponId();
                        Coupon coupon = couponMapper.selectById(couponId);
                        if (!ObjectUtils.isEmpty(coupon)) {
                            coupon.setUsedNum(coupon.getUsedNum() - 1);
                            couponMapper.updateById(coupon);
                        }
                    }
                }

                TaskStatusLog taskStatusLog = new TaskStatusLog();
                taskStatusLog.setStatus(OrderStatusEnum.EXPIRE.getStatus());
                taskStatusLog.setTaskId(orderInfo.getId());
                taskStatusLog.setUserId(orderInfo.getUserId());
                taskStatusLog.setCreateTime(date);
                taskStatusLog.setUpdateTime(date);
                taskStatusLogRest.add(taskStatusLog);

                return orderInfo.getUpdateTime();
            }
        }
        return null;
    }

    @Override
    public OrderDetailResponse getOrderDetail(String id) {
        OrderInfo orderInfo = orderInfoMapper.selectById(id);
        if (ObjectUtils.isEmpty(orderInfo)) {
            throw new RuntimeException("订单不存在");
        }
        String senderTel = orderInfo.getSenderTel();
        String receiverTel = orderInfo.getReceiverTel();
        senderTel = phoneEncoderUtil.decryptString(senderTel);
        receiverTel = phoneEncoderUtil.decryptString(receiverTel);
        orderInfo.setSenderTel(senderTel);
        orderInfo.setReceiverTel(receiverTel);
        OrderDetailResponse orderDetailResponse = BeanUtil.copyProperties(orderInfo, OrderDetailResponse.class);
        QueryWrapper<TaskGoods> taskGoodsQueryWrapper = new QueryWrapper<>();
        taskGoodsQueryWrapper.eq("task_id", orderInfo.getId());
        //获取商品信息
        TaskGoods taskGoods = taskGoodsMapper.selectOne(taskGoodsQueryWrapper);
        if (!ObjectUtils.isEmpty(taskGoods)) {
            CityGoodsType cityGoodsType = cityGoodsTypeMapper.selectById(taskGoods.getGoodsTypeId());
            if (!ObjectUtils.isEmpty(cityGoodsType)) {
                GoodsTypeResponse goodsTypeResponse = BeanUtil.copyProperties(taskGoods, GoodsTypeResponse.class);
                goodsTypeResponse.setGoodsTypeName(cityGoodsType.getName());
                goodsTypeResponse.setGoodsTypeId(cityGoodsType.getId());
                orderDetailResponse.setGoodsTypeResponse(goodsTypeResponse);
            }
        }
        if (!orderInfo.getOrderStatus().equals(OrderStatusEnum.TO_BE_PAID.getStatus())) {
            //获取订单最新信息
            SelectOrderRequest selectOrderRequest = new SelectOrderRequest();
            selectOrderRequest.setTcWaybillNo(orderInfo.getTcWaybillNo());
        }
        String expenseDetailsId = orderInfo.getExpenseDetailsId();
        if (!ObjectUtils.isEmpty(expenseDetailsId)) {
            ExpenseDetails expenseDetails = expenseDetailsMapper.selectById(expenseDetailsId);
            orderDetailResponse.setBasePrice(expenseDetails.getBasePrice());
            orderDetailResponse.setReductionPrice(expenseDetails.getReductionPrice());
        }
        //取件派件中获取骑手坐标
        Integer orderStatus = orderInfo.getOrderStatus();
        if (OrderStatusEnum.TO_BE_DISPATCHED.getStatus().equals(orderStatus)) {
            ErrandOrder errandOrder = errandOrderController.getByOrderSn(orderInfo.getTcWaybillNo(), ErrandOrderTypeEnum.DELIVERY.getValue());
            if (!ObjectUtils.isEmpty(errandOrder)) {
                orderDetailResponse.setLatitude(errandOrder.getLatitude());
                orderDetailResponse.setLongitude(errandOrder.getLongitude());
                orderDetailResponse.setRiderName(errandOrder.getRiderName());
                orderDetailResponse.setErrandOrderSn(errandOrder.getErrandOrderSn());
                String riderPhone = errandOrder.getRiderPhone();
                if (!ObjectUtils.isEmpty(riderPhone)) {
                    orderDetailResponse.setRiderPhone(phoneEncoderUtil.decryptString(riderPhone));
                }
            }

        } else if (OrderStatusEnum.DOOR_TO_DOOR_PICKUP.getStatus().equals(orderStatus) || OrderStatusEnum.DRONE_HAS_BEEN_PICKED_UP.getStatus().equals(orderStatus)) {
            ErrandOrder errandOrder = errandOrderController.getByOrderSn(orderInfo.getTcWaybillNo(), ErrandOrderTypeEnum.COLLECTING.getValue());
            if (!ObjectUtils.isEmpty(errandOrder)) {
                orderDetailResponse.setLatitude(errandOrder.getLatitude());
                orderDetailResponse.setLongitude(errandOrder.getLongitude());
                orderDetailResponse.setRiderName(errandOrder.getRiderName());
                orderDetailResponse.setErrandOrderSn(errandOrder.getErrandOrderSn());
                String riderPhone = errandOrder.getRiderPhone();
                if (!ObjectUtils.isEmpty(riderPhone)) {
                    orderDetailResponse.setRiderPhone(phoneEncoderUtil.decryptString(riderPhone));
                }
            }

        }
        String landingConnId = orderInfo.getLandingConnId();
        String takeoffConnId = orderInfo.getTakeoffConnId();
        //获取派件航站信息
        List<TtTesTerminal> ttTesTerminals = ttTesTerminalRest.selectByConnIds(Arrays.asList(takeoffConnId, landingConnId));
        if (!CollectionUtils.isEmpty(ttTesTerminals)) {
            ttTesTerminals.forEach(ttTesTerminal -> {
                if (landingConnId.equals(ttTesTerminal.getConnId())) {
                    orderDetailResponse.setLandingTerminalLatitude(ttTesTerminal.getLatitude());
                    orderDetailResponse.setLandingTerminalLongitude(ttTesTerminal.getLongitude());
                } else if (takeoffConnId.equals(ttTesTerminal.getConnId())) {
                    orderDetailResponse.setTakeOffTerminalLatitude(ttTesTerminal.getLatitude());
                    orderDetailResponse.setTakeOffTerminalLongitude(ttTesTerminal.getLongitude());
                }
            });

        }

        return orderDetailResponse;
    }

    @Override
    public LogisticsDetailResponse getLogisticsDetail(String id) {
        OrderInfo orderInfo = orderInfoMapper.selectById(id);
        if (ObjectUtils.isEmpty(orderInfo)) {
            throw new RuntimeException("订单不存在");
        }

        String senderTel = orderInfo.getSenderTel();
        String receiverTel = orderInfo.getReceiverTel();
        senderTel = phoneEncoderUtil.decryptString(senderTel);
        receiverTel = phoneEncoderUtil.decryptString(receiverTel);
        orderInfo.setSenderTel(senderTel);
        orderInfo.setReceiverTel(receiverTel);
        LogisticsDetailResponse logisticsDetailResponse = BeanUtil.copyProperties(orderInfo, LogisticsDetailResponse.class);

        String landingConnId = orderInfo.getLandingConnId();
        String takeoffConnId = orderInfo.getTakeoffConnId();
        List<CityAirport> cityAirports = cityAirportRest.selectByConnIds(Arrays.asList(landingConnId, takeoffConnId));
        cityAirports.forEach(cityAirport -> {
            if (cityAirport.getConnId().equals(landingConnId)) {
                logisticsDetailResponse.setLandingConnName(cityAirport.getName());
            } else if (cityAirport.getConnId().equals(takeoffConnId)) {
                logisticsDetailResponse.setTakeOffConnName(cityAirport.getName());
            }
        });
        String senderDoorplate = logisticsDetailResponse.getSenderDoorplate();
        String receiverDoorplate = logisticsDetailResponse.getReceiverDoorplate();
        if (!ObjectUtils.isEmpty(senderDoorplate)) {
            logisticsDetailResponse.setSenderDoorplate(phoneEncoderUtil.decryptString(senderDoorplate));
        }
        if (!ObjectUtils.isEmpty(receiverDoorplate)) {
            logisticsDetailResponse.setReceiverDoorplate(phoneEncoderUtil.decryptString(receiverDoorplate));
        }
        QueryWrapper<TaskGoods> taskGoodsQueryWrapper = new QueryWrapper<>();
        taskGoodsQueryWrapper.eq("task_id", orderInfo.getId());
        //获取商品信息
        TaskGoods taskGoods = taskGoodsMapper.selectOne(taskGoodsQueryWrapper);
        if (!ObjectUtils.isEmpty(taskGoods)) {
            CityGoodsType cityGoodsType = cityGoodsTypeMapper.selectById(taskGoods.getGoodsTypeId());
            if (!ObjectUtils.isEmpty(cityGoodsType)) {
                logisticsDetailResponse.setGoodsTypeName(cityGoodsType.getName());
            }
        }
        logisticsDetailResponse.setSurcharge(new BigDecimal(0));
        logisticsDetailResponse.setGoodsVolume("≤ 67*37*25cm");
        String expenseDetailsId = orderInfo.getExpenseDetailsId();
        if (!ObjectUtils.isEmpty(expenseDetailsId)) {
            ExpenseDetails expenseDetails = expenseDetailsMapper.selectById(expenseDetailsId);
            logisticsDetailResponse.setBasePrice(expenseDetails.getBasePrice());
            logisticsDetailResponse.setReductionPrice(expenseDetails.getReductionPrice());
        }
        return logisticsDetailResponse;
    }

    @Override
    public List<TaskStatusLogResponse> getTaskStatusLog(String taskId) {
        List<TaskStatusLog> taskStatusLogs = taskStatusLogRest.selectListByTaskId(taskId);
        List<TaskStatusLogResponse> taskStatusLogResponses = BeanUtil.copyProperties(taskStatusLogs, TaskStatusLogResponse.class);
        return taskStatusLogResponses;
    }

    @Override
    public List<TaskStatusLogResponse> getFeedbackStatusLog(String feedbackId) {
        List<FeedbackStatusLog> feedbackStatusLogs = feedbackStatusLogRest.selectListByFeedbackId(feedbackId);
        List<TaskStatusLogResponse> taskStatusLogResponses = BeanUtil.copyProperties(feedbackStatusLogs, TaskStatusLogResponse.class);
        return taskStatusLogResponses;
    }

    @Override
    public RespJsonPageData<UserFeedbackResponse> getFeedbacks(Integer page, Integer size, String userId) {
        Page<Feedback> feedbackPage = feedbackRest.selectPageListByUserId(page, size, userId);
        List<UserFeedbackResponse> userFeedbackResponses = new ArrayList<>();
        List<String> orderIds = feedbackPage.getRecords().stream().map(Feedback::getOrderId).collect(Collectors.toList());
        List<OrderInfo> orderInfos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(orderIds)) {
            QueryWrapper<OrderInfo> orderInfoQueryWrapper = new QueryWrapper<>();
            orderInfoQueryWrapper.in("id", orderIds);
            orderInfos = orderInfoMapper.selectList(orderInfoQueryWrapper);
        }
        List<OrderInfo> finalOrderInfos = orderInfos;
        feedbackPage.getRecords().forEach(feedback -> {
            UserFeedbackResponse userFeedbackResponse = new UserFeedbackResponse();
            userFeedbackResponse.setCreateTime(feedback.getCreateTime());
            userFeedbackResponse.setWorkOrderNum(feedback.getWorkOrderNum());
            userFeedbackResponse.setStatus(feedback.getStatus());
            userFeedbackResponse.setOrderId(feedback.getOrderId());
            finalOrderInfos.forEach(orderInfo -> {
                if (feedback.getOrderId().equals(orderInfo.getId())) {
                    userFeedbackResponse.setSenderName(orderInfo.getSenderName());
                    userFeedbackResponse.setSendAddressName(orderInfo.getSendAddressName());
                    userFeedbackResponse.setReceiverName(orderInfo.getReceiverName());
                    userFeedbackResponse.setReceiveAddressName(orderInfo.getReceiveAddressName());
                    userFeedbackResponse.setOrderStatus(orderInfo.getOrderStatus());
                    userFeedbackResponse.setTcWaybillNo(orderInfo.getTcWaybillNo());
                }
            });
            userFeedbackResponses.add(userFeedbackResponse);
        });
        return RespJsonPageData.success(userFeedbackResponses, feedbackPage.getTotal());
    }

    @Override
    public void updateGoods(TaskGoodsRequest taskGoodsRequest) {


        QueryWrapper<TaskGoods> taskGoodsQueryWrapper = new QueryWrapper<>();
        taskGoodsQueryWrapper.eq("task_id", taskGoodsRequest.getTaskId());
        TaskGoods taskGoods = taskGoodsMapper.selectOne(taskGoodsQueryWrapper);
        if (!ObjectUtils.isEmpty(taskGoods)) {

            UpdateOrderRequest updateOrderRequest = new UpdateOrderRequest();
            Task task = taskMapper.selectById(taskGoodsRequest.getTaskId());
            if (!task.getStatus().equals(TaskStatusNum.WAIT_CONFIRM.getStatus())) {
                throw new BusinessException(ErrorEnum.NOT_WAIT_CONFIRM);
            }
            taskGoods.setGoodsTypeId(taskGoodsRequest.getGoodsTypeId());
            taskGoods.setName(taskGoodsRequest.getGoodsName());
            taskGoods.setUpdateTime(new Date());
            taskGoodsMapper.updateById(taskGoods);


            if (!ObjectUtils.isEmpty(task)) {
                updateOrderRequest.setOrderCode(task.getOrderCode());
            }
            GoodsType goodsType = goodsTypeMapper.selectById(taskGoodsRequest.getGoodsTypeId());
            if (!ObjectUtils.isEmpty(goodsType)) {
                updateOrderRequest.setGoodsType(goodsType.getCode());
            }
            updateOrderRequest.setGoodsInfo(taskGoodsRequest.getGoodsName());
            JSONObject jsonObject = airStationRest.modifyOrder(updateOrderRequest);
            if (!jsonObject.getBoolean("success")) {
                throw new RuntimeException(jsonObject.get("errorMessage").toString());
            }
        }
    }
}
